/*
 *  相对位置的计算
 */
#include "view.h"
#include "view_def.h"
#include "view_relative.h"

/* ----- 位置范围计算 ----- */

int32_t View::Resize()
{
    /* --- 相对对象确认 --- */

    bool isRelativeParent = false;
    View* rView = NULL;
    /* 相对对象为控件 */
    if (m_info.rObj)
    {
        /* 在同级链表中,通过序号定位到对象 */
        rView = (View*)CrossList::At(Index() + m_info.rObj);
        /* 对象未完成Resize */
        if (rView && !rView->IsNeedResize())
        {
            /* 为防止相互依赖导致死锁,先标记当前控件已Resize标志 */
            m_resizeFlag = Parent()->GetResizeFlag();
            /* 再Resize相对对象 */
            rView->OnCallback(VCT_RESIZE);
        }
    }
    /* 相对对象为父控件 */
    if (!rView)
    {
        rView = Parent();
        isRelativeParent = true;
    }

    /* --- 大小计算输出: shapeWidth, shapeHeight --- */

    /* 相对大小计算失败时,切换为自动模式(根据文本大小设置控件大小) */
    bool autoWidth = false;
    bool autoHeight = false;

    /* 大于0,此为绝对值大小 */
    if (m_info.width > VRS_AUTO)
    {
        m_shapeWidth = m_info.width - (m_info.shapeMarginLeft + m_info.shapeMarginRight);
    }
    /* 小于0,此为相对大小,npm为当前控件在相对控件的倍数 */
    else if (m_info.width < VRS_AUTO && rView)
    {
        float npm = (float)m_info.width / VRS_MATCH;
        m_shapeWidth = (int32_t)(rView->GetWidth() * npm) - (m_info.shapeMarginLeft + m_info.shapeMarginRight);
    }
    else
    {
        autoWidth = true;
    }

    /* 大于0,此为绝对值大小 */
    if (m_info.height > VRS_AUTO)
    {
        m_shapeHeight = m_info.height - (m_info.shapeMarginTop + m_info.shapeMarginBottom);
    }
    /* 小于0,此为相对大小,npm为当前控件在相对控件的倍数 */
    else if (m_info.height < VRS_AUTO && rView)
    {
        float npm = (float)m_info.height / VRS_MATCH;
        m_shapeHeight = (int32_t)(rView->GetHeight() * npm) - (m_info.shapeMarginTop + m_info.shapeMarginBottom);
    }
    else
    {
        autoHeight = true;
    }

    /* 文本大小计算 */
    ResizeText(autoWidth, autoHeight, m_info.textCenterX, m_info.textCenterY);

    /* --- 相对方式和位置计算输出: shapeX, shapeY --- */

    if (rView)
    {
        /* 横向位置 */
        if (m_info.rType & VRT_CENTER_X || m_info.rType & VRT_CENTER)
        {
            m_shapeX = rView->GetX() + (rView->GetWidth() - m_shapeWidth) / 2;
        }
        else if (m_info.rType & VRT_LEFT)
        {
            m_shapeX = isRelativeParent ? 
                rView->GetX() :
                rView->GetX() - m_shapeWidth;
        }
        else if (m_info.rType & VRT_RIGHT)
        {
            m_shapeX = isRelativeParent ? 
                rView->GetX() + rView->GetWidth() - m_shapeWidth :
                rView->GetX() + rView->GetWidth();
        }
        else
            m_shapeX = rView->GetX();

        /* 纵向位置 */
        if (m_info.rType & VRT_CENTER_Y || m_info.rType & VRT_CENTER)
        {
            m_shapeY = rView->GetY() + (rView->GetHeight() - m_shapeHeight) / 2;
        }
        else if (m_info.rType & VRT_TOP)
        {
            m_shapeY = isRelativeParent ? 
                rView->GetY() :
                rView->GetY() - m_shapeHeight;
        }
        else if (m_info.rType & VRT_BOTTOM)
        {
            m_shapeY = isRelativeParent ? 
                rView->GetY() + rView->GetHeight() - m_shapeHeight :
                rView->GetY() + rView->GetHeight();
        }
        else
            m_shapeX = rView->GetY();
    }
    /* 当前view为顶层控件 */
    else
    {
        m_shapeX = 0;
        m_shapeY = 0;
    }

    return 0;
}

int32_t View::ResizeText(bool autoWidth, bool autoHeight, bool centerX, bool centerY)
{
    char* str = NULL;
    View* parent = Parent();
    bool resizeFalse = true;

    /* 重置 */
    m_textWidth = 0;
    m_textHeight = 0;
    /* 文字左上角相对控件偏移 */
    m_textXErr = m_info.textMarginLeft;
    m_textYErr = m_info.textMarginTop;

    do
    {
        /* 文本内容为空 */
        if (m_info.text.IsEmpty())
            break;

        /* 当控件范围需要文本范围反推时,才需要计算文本范围 */
        if (autoWidth || autoHeight || centerX || centerY)
        {
            int32_t lineLimit = 0;

            /* 传参准备 */
            if (autoWidth && parent)
                lineLimit = parent->GetWidth();

            str = new char[VIEW_TEXT_PARSE_SIZE + 1]();
            if (!str)
                break;

            /* 先把文本内容转换为字符串 */
            if (m_info.text.GetPrint(str, VIEW_TEXT_PARSE_SIZE) < 1)
                break;

            /* 再把 str 拿到 ViewFont 计算范围 */
            if (ViewFont::GetVF()->SizeOf(
                str,
                m_info.textFont,
                m_info.textSize,
                m_info.textBold,
                m_info.textSpaceX,
                m_info.textSpaceY,
                lineLimit,
                m_info.textDegree,
                m_textWidth,
                m_textHeight) != 0)
            {
                break;
            }

            /* 根据文本大小反推控件大小 */
            if (autoWidth)
                m_shapeWidth = m_textWidth + m_info.textMarginLeft + m_info.textMarginRight;
            if (autoHeight)
                m_shapeHeight = m_textHeight + m_info.textMarginTop + m_info.textMarginBottom;

            /* 文字左上角相对控件偏移 */
            m_textXErr = m_info.textMarginLeft;
            if (centerX)
                m_textXErr += (m_shapeWidth - (m_info.textMarginLeft + m_info.textMarginRight) - m_textWidth) / 2;

            m_textYErr = m_info.textMarginTop;
            if (centerY)
                m_textYErr += (m_shapeHeight - (m_info.textMarginTop + m_info.textMarginBottom) - m_textHeight) / 2;
        }
        else
        {
            /* 文字范围*/
            m_textWidth = m_shapeWidth - m_info.textMarginLeft - m_info.textMarginRight;
            m_textHeight = m_shapeHeight - m_info.textMarginTop - m_info.textMarginBottom;
        }

        resizeFalse = false;

    } while (0);

    if (str)
        delete[] str;
    if (!resizeFalse)
        return 0;

    /* 自动宽高设置为父控件的宽高,除以同级控件个数 */
    if (parent)
    {
        if (autoWidth)
            m_shapeWidth = parent->GetWidth() / parent->ChildNum();
        if (autoHeight)
            m_shapeHeight = parent->GetHeight() / parent->ChildNum();
    }
    else
    {
        if (autoWidth)
            m_shapeWidth = 0;
        if (autoHeight)
            m_shapeHeight = 0;
    }

    return 0;
}
